#include <bits/stdc++.h>
using namespace std;
int t,n,m,len,k,ans1,ans2,s;
int x[100005],y[100005],z[100005];
int res[100005],speed[1000005];
struct node
{
	int lp,rp;
	friend bool operator < (node a,node b)
	{
		if (a.rp!=b.rp)
		{
			return a.rp<b.rp;
		}
		return a.lp<b.lp;
	}
}v[100005];
void add(int l,int r)
{
	if (l<=r and speed[r]!=speed[l-1])
	{
		ans1++;
		v[++s]={l,r};
	}
	return;
}
int main()
{
	freopen("detect.in","r",stdin);
	freopen("detect.out","w",stdout);
	cin >> t;
	for (int i=1;i<=t;i++)
	{
		cin >> n >> m >> len >> k;
		s=0;ans1=0;ans2=0;
		memset(speed,0,sizeof(speed));
		for (int j=1;j<=n;j++)
		{
			cin >> x[j] >> y[j] >> z[j];
			x[j]++;
		}
		for (int j=1;j<=m;j++)
		{
			cin >> res[j];
			res[j]++;
			speed[res[j]]++;
		}
		for (int j=1;j<=1e6+1;j++)
		{
			speed[j]+=speed[j-1];
		}
		for (int j=1;j<=n;j++)
		{
			if (z[j]==0)
			{
				if (y[j]>k)
				{
					add(x[j],len+1);
				}
			}
			else
			{
				double pos=double(k*k-y[j]*y[j])/double(2*z[j]);
				if (pos<0)
				{
					if (z[j]>0)
					{
						add(x[j],len+1);
					}
					else
					{
						continue;
					}
				}
				else
				{
					if (z[j]>0)
					{
						add(x[j]+int(pos+1),len+1);
					}
					else
					{
						if (int(pos)==pos)
						{
							pos--;
						}
						add(x[j],x[j]+int(pos));
					}
				}
			}
		}
		sort(v+1,v+s+1);
		int tx=1;int ty=1;
		while (ty<=s)
		{
			while (res[tx+1]<=v[ty].rp and tx<m)
			{
				tx++;
			}
			while (v[ty].lp<=res[tx] and ty<=n)
			{
				ty++;
			}
			ans2++;
		}
		cout << ans1 << ' ' << m-ans2 << endl;
	} 
}
